package com.zsqat.eshop.auth.controller;

import com.alibaba.fastjson.TypeReference;
import com.zsqat.common.constant.AuthConstant;
import com.zsqat.common.utils.R;
import com.zsqat.common.vo.MemberResponseVo;
import com.zsqat.eshop.auth.feign.MemberFeignService;
import com.zsqat.eshop.auth.vo.UserLoginVo;
import com.zsqat.eshop.auth.vo.UserRegisterVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import java.util.HashMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.Map;
import java.util.stream.Collectors;

@Controller
public class LoginController {
  @Autowired
  private MemberFeignService memberFeignService;

  @Autowired
  private StringRedisTemplate redisTemplate;
  // 用户没有登录过跳转到登录页面，如果登录过就跳转到首页
  @GetMapping(value = "/login.html")
  public String loginPage(HttpSession session) {
    // 从session先取出来用户的信息，判断用户是否已经登录过了
    Object attribute = session.getAttribute(AuthConstant.LOGIN_USER);
    // 如果用户没登录那就跳转到登录页面
    if (attribute == null) {
      return "login";
    } else {
      return "redirect:http://eshop.com";
    }
  }

  // 处理登录业务逻辑
  @PostMapping(value = "/login")
  public String login(UserLoginVo userLoginVo, RedirectAttributes attributes, HttpSession session) {
    // 远程登录
    R login = memberFeignService.login(userLoginVo);
    if (login.getCode() == 0) {
      MemberResponseVo data = login.getData("data", new TypeReference<MemberResponseVo>() {});
      session.setAttribute(AuthConstant.LOGIN_USER, data);
      return "redirect:http://eshop.com";
    } else {
      Map<String,String> errors = new HashMap<>();
      errors.put("msg", login.getData("msg", new TypeReference<String>(){}));
      attributes.addFlashAttribute("errors", errors);
      return "redirect:http://auth.eshop.com/login.html";
    }
  }

  /**
   *
   * TODO: 重定向携带数据：利用session原理，将数据放在session中。
   * TODO:只要跳转到下一个页面取出这个数据以后，session里面的数据就会删掉
   * TODO：分布下session问题
   * RedirectAttributes：重定向也可以保留数据，不会丢失
   * 用户注册
   * @return
   */
  @PostMapping(value = "/register")
  public String register(@Valid UserRegisterVo userRegisterVo, BindingResult result,
                         RedirectAttributes attributes) {
    // 如果有错误回到注册页面
    if (result.hasErrors()) {
      Map<String, String> errors = result.getFieldErrors().stream().collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage));
      attributes.addFlashAttribute("errors", errors);

      // 校验出错回到注册页面
      return "redirect:http://auth.eshop.com/reg.html";
    }

    // 1.校验验证码
    String code = userRegisterVo.getCode();

    // 获取存入Redis里的验证码
    String redisCode = redisTemplate.opsForValue().get(AuthConstant.SMS_CODE_CACHE_PREFIX + userRegisterVo.getPhone());
    if (!StringUtils.isEmpty(redisCode)) {
      // 截取字符串
      if (code.equals(redisCode.split("_")[0])) {
        // 删除验证码;令牌机制
        redisTemplate.delete(AuthConstant.SMS_CODE_CACHE_PREFIX + userRegisterVo.getPhone());
        // 验证码通过，真正注册，调用远程服务进行注册
        R register = memberFeignService.register(userRegisterVo);
        if (register.getCode() == 0) {
          // 成功
          return "redirect:http://auth.eshop.com/login.html";
        } else {
          // 失败
          Map<String, String> errors = new HashMap<>();
          errors.put("msg", register.getData("msg", new TypeReference<String>(){}));
          attributes.addFlashAttribute("errors", errors);
          return "redirect:http://auth.eshop.com/reg.html";
        }
      } else {
        // 校验出错回到注册页面
        Map<String, String> errors = new HashMap<>();
        errors.put("code", "验证码错误");
        attributes.addFlashAttribute("errors", errors);
        return "redirect:http://auth.eshop.com/reg.html";
      }
    } else {
      // 校验出错回到注册页面
      Map<String, String> errors = new HashMap<>();
      errors.put("code", "验证码错误");
      attributes.addFlashAttribute("errors", errors);
      return "redirect:http://auth.eshop.com/reg.html";
    }
  }

  // 登出，注销
  @GetMapping(value = "/loguot.html")
  public String logout(HttpServletRequest request) {
    request.getSession().removeAttribute(AuthConstant.LOGIN_USER);
    request.getSession().invalidate();
    return "redirect:http://eshop.com";
  }


}
